cmake_minimum_required(VERSION 3.6)

# 查找源文件的根目录
STRING(LENGTH "${sgbd_root_dir}" sgbd_root_dir_length)
if (${sgbd_root_dir_length} EQUAL 0)
    set(sgbd_root_dir ${CMAKE_CURRENT_LIST_DIR}/)
endif()

# 目录分组
macro(CC_SOURCE_GROUP_BY_DIR source_files)       
    if (GROUP_BY_DIR)
	set(sgbd_cur_dir ${CMAKE_CURRENT_SOURCE_DIR}/)
	foreach(sgbd_file ${${source_files}})
        string(REGEX REPLACE ${sgbd_root_dir} "" sgbd_repath ${sgbd_file} )
		string(REGEX REPLACE ${sgbd_cur_dir} "" sgbd_fpath ${sgbd_repath})
		string(REGEX REPLACE "[^/\\\\]+$" "" sgbd_group_name ${sgbd_fpath})
		if(sgbd_group_name)
			string(REPLACE "/"   "\\\\"  sgbd_group_name_normal ${sgbd_group_name})
			source_group(${sgbd_group_name_normal} FILES ${sgbd_file})
        endif(sgbd_group_name)
	endforeach(sgbd_file)
    endif(GROUP_BY_DIR)
endmacro(CC_SOURCE_GROUP_BY_DIR)

# 采集源代码
macro (CC_COLLECT_COMPLIE_SOURCE in_soruce_root_dir out_source_file_list)
    file(GLOB ${out_source_file_list}
        ${in_soruce_root_dir}/*.cpp
        ${in_soruce_root_dir}/*.c 
        ${in_soruce_root_dir}/*.cc
        ${in_soruce_root_dir}/*.hh
        ${in_soruce_root_dir}/*.hpp 
        ${in_soruce_root_dir}/*.h
        ${in_soruce_root_dir}/*.mm
        ${in_soruce_root_dir}/*.m
    )
endmacro (CC_COLLECT_COMPLIE_SOURCE)

# 遍历采集源代码
macro (CC_COLLECT_COMPLIE_SOURCE_RECURSE in_soruce_root_dir out_source_file_list)
    file(GLOB_RECURSE ${out_source_file_list}
        ${in_soruce_root_dir}/*.cpp
        ${in_soruce_root_dir}/*.c 
        ${in_soruce_root_dir}/*.cc
        ${in_soruce_root_dir}/*.hh
        ${in_soruce_root_dir}/*.hpp 
        ${in_soruce_root_dir}/*.h
        ${in_soruce_root_dir}/*.mm
        ${in_soruce_root_dir}/*.m
    )
endmacro (CC_COLLECT_COMPLIE_SOURCE_RECURSE)



# 采集源代码，并根据目录分组
macro(all_source CC_SOURCES)
    CC_COLLECT_COMPLIE_SOURCE(${CMAKE_CURRENT_LIST_DIR} cc_complie_sources)
    CC_SOURCE_GROUP_BY_DIR(cc_complie_sources)
    list(APPEND ${CC_SOURCES} ${cc_complie_sources})    
endmacro(all_source)

# 遍历采集源代码，并根据目录分组
macro(all_source_recurse CC_SOURCES)
    CC_COLLECT_COMPLIE_SOURCE_RECURSE(${CMAKE_CURRENT_LIST_DIR} cc_complie_sources)
    CC_SOURCE_GROUP_BY_DIR(cc_complie_sources)
    list(APPEND ${CC_SOURCES} ${cc_complie_sources})    
endmacro(all_source_recurse)

# 打印文件目录
macro(print_files files)
    set(sgbd_cur_dir ${CMAKE_CURRENT_SOURCE_DIR}/)
    foreach(sgbd_file ${${files}})
        string(REGEX REPLACE ${sgbd_root_dir} "" sgbd_repath ${sgbd_file} )
        message(${sgbd_repath})
    endforeach(sgbd_file)
endmacro(print_files)


# 遍历采集源代码
macro (PROTO_COLLECT_COMPLIE_SOURCE_RECURSE in_soruce_root_dir out_source_file_list)
    file(GLOB_RECURSE ${out_source_file_list}
        ${in_soruce_root_dir}/*.proto
    )
endmacro (PROTO_COLLECT_COMPLIE_SOURCE_RECURSE)

# 父目录
macro(PARENT_DIR source_file parentDir)       
	set(sgbd_cur_dir ${CMAKE_CURRENT_SOURCE_DIR}/)
    # string(REGEX REPLACE ${sgbd_root_dir} "" sgbd_repath ${source_file} )
    string(REGEX REPLACE ${sgbd_cur_dir} "" sgbd_fpath ${source_file})
    # message(${sgbd_fpath})
    string(REGEX REPLACE "[^/\\\\]+$" "" ${parentDir} ${sgbd_fpath})
endmacro(PARENT_DIR)

# 遍历采集 protobuf 源代码，并根据目录分组
macro(all_proto_recurse PROTO_SOURCES)
    PROTO_COLLECT_COMPLIE_SOURCE_RECURSE(${CMAKE_CURRENT_LIST_DIR} proto_complie_sources)
    CC_SOURCE_GROUP_BY_DIR(proto_complie_sources)
    list(APPEND ${PROTO_SOURCES} ${proto_complie_sources})    
endmacro(all_proto_recurse)


# #设置输出路径
# (MESSAGE_DIR ${CMAKE_BINARY_DIR}/message)
# if(EXISTS "${CMAKE_BINARY_DIR}/message" AND IS_DIRECTORY "${CMAKE_BINARY_DIR}/message")
#         SET(DST_DIR ${MESSAGE_DIR})
# else()
#         file(MAKE_DIRECTORY ${MESSAGE_DIR})
#         SET(DST_DIR ${MESSAGE_DIR})
# endif()


macro(protobuf_cpp TARGET_NAME protos out_dir MESSAGE_SRC MESSAGE_HDRS)
    message("-- protobuf_cpp "  ${out_dir})
    message("-- TARGET_NAME  " ${TARGET_NAME})
    if(NOT EXISTS ${out_dir})
        message(--- MAKE_DIRECTORY > ${out_dir})

        file(MAKE_DIRECTORY ${out_dir})
    endif()
    foreach(msg ${${protos}})
        get_filename_component(FIL_WE ${msg} NAME_WE)
        PARENT_DIR(${msg} p_dir)
        string(REGEX REPLACE "[^/\\\\]+$" "" DIR ${msg})

        set(SRC "${out_dir}/${p_dir}${FIL_WE}.pb.cc")
        set(HEADER "${out_dir}/${p_dir}${FIL_WE}.pb.h")
        if(NOT EXISTS ${out_dir}/${p_dir})
            file(MAKE_DIRECTORY ${out_dir}/${p_dir})
        endif()

        list(APPEND ${MESSAGE_SRC} ${SRC})
        list(APPEND ${MESSAGE_HDRS} ${HEADER})

        # 使用自定义命令
        add_custom_command(
            OUTPUT 
                ${SRC}
                ${HEADER}
            # COMMAND  "c:/usr/protobuf/bin/protoc.exe"
            COMMAND ${Protobuf_PROTOC_EXECUTABLE}
            ARGS 
                --cpp_out  ${out_dir}/${p_dir}
                -I ${DIR}
                ${FIL_WE}.proto
            DEPENDS ${msg}
            COMMENT "Running C++ protocol buffer compiler on ${msg}"
            VERBATIM
        )
    endforeach()

    # 设置文件属性为 GENERATED
    set_source_files_properties(${${MESSAGE_SRC}} ${${MESSAGE_HDRS}} PROPERTIES GENERATED TRUE)
    # 添加自定义target
    add_custom_target(${TARGET_NAME} ALL
                    DEPENDS ${${MESSAGE_SRC}} ${${MESSAGE_HDRS}}
                    COMMENT "generate message " ${TARGET_NAME}
                    VERBATIM
    )
endmacro(protobuf_cpp)



macro(protobuf_cpp_ protos out_dir MESSAGE_SRC MESSAGE_HDRS)
    foreach(msg ${${protos}})
        get_filename_component(FIL_WE ${msg} NAME_WE)
        PARENT_DIR(${msg} p_dir)
        
        
        string(REGEX REPLACE "[^/\\\\]+$" "" DIR ${msg})
        message(${DIR})

        list(APPEND ${MESSAGE_SRC} "${DIR}${FIL_WE}.pb.cc")
        list(APPEND ${MESSAGE_HDRS} "${DIR}${FIL_WE}.pb.h")

        # 使用自定义命令
        add_custom_command(
            OUTPUT 
                "${DIR}${FIL_WE}.pb.cc"
                "${DIR}${FIL_WE}.pb.h"
            COMMAND  protoc
            ARGS 
                --cpp_out ${DIR}
                -I ${DIR}
                ${FIL_WE}.proto
            DEPENDS ${msg}
            COMMENT "Running C++ protocol buffer compiler on ${msg}"
            VERBATIM
        )
    endforeach()

    # 设置文件属性为 GENERATED
    set_source_files_properties(${${MESSAGE_SRC}} ${${MESSAGE_HDRS}} PROPERTIES GENERATED TRUE)
    # 添加自定义target
    add_custom_target(generate_message ALL
                    DEPENDS ${${MESSAGE_SRC}} ${${MESSAGE_HDRS}}
                    COMMENT "generate message target"
                    VERBATIM
    )
endmacro(protobuf_cpp_)

macro(test_project)
    file(GLOB_RECURSE CC_SOURCES
        ${CMAKE_CURRENT_LIST_DIR}/*.cpp
        ${CMAKE_CURRENT_LIST_DIR}/*.c 
        ${CMAKE_CURRENT_LIST_DIR}/*.cc
    )

    foreach(sgbd_file ${CC_SOURCES})
        # 使用正则表达式提取文件名
        string(REGEX MATCH "[^/\\\\]+(\.cpp)$" file_name ${sgbd_file})
        string(REGEX REPLACE "\.cpp" "" extracted_file_name ${file_name})
        # message(extracted_file_name:${extracted_file_name})
        add_executable(${extracted_file_name} ${sgbd_file})
    endforeach(sgbd_file)
endmacro(test_project)